//
//  TakePictureVC.swift
//  证件拍照
//
//  Created by 千策万划-mini on 2025/5/3.
//

import AVFoundation
import Foundation
import Photos
import UIKit

class TakePictureVC: BaseTableVC, AVCaptureMetadataOutputObjectsDelegate, CAAnimationDelegate {

    var cardType: String = ""
    var productCode: String = ""
    var image: UIImage = .init() // 拍到的照片
    var imageDict: [String: Any]?
    var blockUploadImageSuccess:((ModelUserIdentityInfoOther) -> Void)?
    
    // MARK: - lazy
    var session: AVCaptureSession = .init()
    lazy var previewLayer: AVCaptureVideoPreviewLayer = {
        let result = AVCaptureVideoPreviewLayer(session: self.session)
        result.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: SCREEN_HEIGHT)
        result.videoGravity = .resizeAspectFill
        return result
    }()

    lazy var imageOutPut: AVCaptureStillImageOutput = .init()

    lazy var device: AVCaptureDevice? = AVCaptureDevice.default(for: .video)

    // 初始化输入
    lazy var input: AVCaptureDeviceInput? = {
        guard let device = self.device else { return nil }
        return try? AVCaptureDeviceInput(device: device)
    }()

    // 初始化输出
    lazy var output: AVCaptureMetadataOutput = .init()

    lazy var topView: UIView = {
        let result = UIView()
        result.widthHeight = XY(SCREEN_WIDTH, (SCREEN_HEIGHT - W(410)) / 2)
        result.leftTop = XY(0, 0)
        result.backgroundColor = .clear
        return result
    }()

    lazy var navView: BaseNavView = {
        let result = BaseNavView()
        result.resetNavBackTitle(title: "Photograph", rightView: nil)
        result.leftTop = XY(0, 0)
        result.backgroundColor = .clear
        result.backBtn.isHidden = true
        result.lineBottom.isHidden = true
        result.blockBack = { [weak self] in
            guard let self = self else { return }
            self.pop()
        }
        return result
    }()

    lazy var bottomView: UIView = {
        let result = UIView()
        result.widthHeight = XY(SCREEN_WIDTH, (SCREEN_HEIGHT - W(410)) / 2)
        result.leftBottom = XY(0, SCREEN_HEIGHT)
        result.backgroundColor = .clear
        return result
    }()

    lazy var photoButton: UIButton = {
        let result = UIButton()
        result.widthHeight = XY(W(75), W(75))
        result.centerXCenterY = XY(SCREEN_WIDTH / 2, self.bottomView.height / 2)
        result.setImage(UIImage(named: "icon_auth_take_picture"), for: .normal)
        result.tag = 3
        result.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        return result
    }()

    lazy var reCamButton: UIButton = {
        let result = UIButton()
        result.widthHeight = XY(W(80), W(40))
        result.leftCenterY = XY(0, self.photoButton.centerY)
        result.isHidden = true
        result.tag = 2
        result.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        let label = OutlineLabel()
        label.resetView(
            title: "again",
            textColor: COLOR_WHITE(),
            font: UIFont.customBoldFont(size: 20),
            shadowColor: UIColor(hex: "#2D0084"),
            outlineColor: UIColor(hex: "#2D0084"),
            strokeColor: "#F78D0F"
        )
        label.centerXCenterY = XY(result.width / 2, result.height / 2)
        result.addSubview(label)
        return result
    }()

    lazy var selectButton: UIButton = {
        let result = UIButton()
        result.widthHeight = XY(W(80), W(40))
        result.rightCenterY = XY(SCREEN_WIDTH - 7, self.photoButton.centerY)
        result.isHidden = true
        result.tag = 4
        result.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        let label = OutlineLabel()
        label.resetView(
            title: "confirm",
            textColor: COLOR_WHITE(),
            font: UIFont.customBoldFont(size: 20),
            shadowColor: UIColor(hex: "#2D0084"),
            outlineColor: UIColor(hex: "#2D0084"),
            strokeColor: "#F78D0F"
        )
        label.centerXCenterY = XY(result.width / 2, result.height / 2)
        result.addSubview(label)
        return result
    }()

    lazy var closeButton: UIButton = {
        let result = UIButton()
        result.widthHeight = XY(W(50), W(50))
        result.leftCenterY = XY(W(15), self.photoButton.centerY)
        result.setImage(UIImage(named: "icon_nav_back"), for: .normal)
        result.tag = 5
        result.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        return result
    }()

    lazy var flashButton: UIButton = {
        let result = UIButton()
        result.widthHeight = XY(W(50), W(50))
        result.rightCenterY = XY(SCREEN_WIDTH - W(15), self.photoButton.centerY)
        result.setImage(UIImage(named: "icon_auth_flash_lamp"), for: .normal)
        result.tag = 6
        result.addTarget(self, action: #selector(btnClick(_:)), for: .touchUpInside)
        return result
    }()

    // MARK: - viewDidLoad
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        configCamera()
        configUI()
    }

    func configUI() {
        view.backgroundColor = .clear
        view.addSubview(topView)
        view.addSubview(bottomView)
        topView.addSubview(navView)
        bottomView.addSubview(photoButton)
        bottomView.addSubview(reCamButton)
        bottomView.addSubview(selectButton)
        bottomView.addSubview(closeButton)
        bottomView.addSubview(flashButton)
    }

    func configCamera() {
        GlobalMethod.showLoadingView()
        // 生成会话，用来结合输入输出
        session = AVCaptureSession()
        if session.canSetSessionPreset(.photo) {
            session.sessionPreset = .photo
        }
        if let input = input, session.canAddInput(input) {
            session.addInput(input)
            // 添加防抖
            configureCameraPreview(device)
        }
        if session.canAddOutput(imageOutPut) {
            session.addOutput(imageOutPut)
        }
        view.layer.addSublayer(previewLayer)

        DispatchQueue.global(qos: .default).async {
            // 在后台线程中执行 startRunning 方法
            self.session.startRunning()
            // 切换到主线程更新 UI
            DispatchQueue.main.async {
                // 在主线程中更新 UI，隐藏 loadingView
                GlobalMethod.hideLoadingView()
            }
            // 打点
            // GlobalMethod.userBehaviorRecordWithPageName("VerifyKtp", action: "ID_Front_Camera_Init", extInfo: nil)
        }

        if let device = device {
            do {
                try device.lockForConfiguration()
                if device.isFlashModeSupported(.auto) {
                    device.flashMode = .auto
                }
                // 自动白平衡
                if device.isWhiteBalanceModeSupported(.autoWhiteBalance) {
                    device.whiteBalanceMode = .autoWhiteBalance
                }
                device.unlockForConfiguration()
            } catch {
                print("配置相机失败: \(error)")
            }
        }
    }

    // MARK: - 事件
    func pop() {
//        [self.imageView removeFromSuperview];
        session.stopRunning()
        GB_Nav?.popViewController(animated: true)
    }

    // 重新拍照
    func againPhotoClick() {
        DispatchQueue.global(qos: .default).async {
            // 在后台线程中执行 startRunning 方法
            self.session.startRunning()
        }
        resetButtonStatus(isShowPhotoBtn: true)
    }

    // 重置底部按钮状态
    func resetButtonStatus(isShowPhotoBtn: Bool) {
        if isShowPhotoBtn {
            photoButton.isHidden = false
            reCamButton.isHidden = true
            selectButton.isHidden = true
        } else {
            photoButton.isHidden = true
            reCamButton.isHidden = false
            selectButton.isHidden = false
        }
        closeButton.isHidden = !reCamButton.isHidden
        flashButton.isHidden = closeButton.isHidden
    }

    // 拍照
    func takePicture() {
        if let videoConnection = imageOutPut.connection(with: .video) {
            imageOutPut.captureStillImageAsynchronously(from: videoConnection) { imageDataSampleBuffer, _ in
                guard let buffer = imageDataSampleBuffer else {
                    print("take photo failed!")
                    return
                }
                if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer),
                   let image = UIImage(data: imageData)
                {
                    self.image = image
                    self.imageDict = ["image": image, "info": ["PHImageFileUTIKey": ".jpeg"]]
                    self.session.stopRunning()
                    print("image size = \(image.size)")
                    self.resetButtonStatus(isShowPhotoBtn: false)
                }
            }
        } else {
            print("take photo failed!")
            return
        }
    }

    // 拍照防抖
    func configureCameraPreview(_: AVCaptureDevice?) {
        for connection in imageOutPut.connections {
            for port in connection.inputPorts {
                if port.mediaType == .video {
                    if connection.isVideoStabilizationSupported {
                        connection.preferredVideoStabilizationMode = .auto
                        print("视频稳定已启用")
                    } else {
                        print("该设备的当前格式不支持视频稳定。")
                    }
                    break
                }
            }
        }
    }

    // 确认选择
    func confirmSelectPhoto() {
        requestOSSUploadPositive()
    }

    // MARK: - 点击事件
    @objc func btnClick(_ sender: UIControl) {
        feedback()
        sender.addClickAnimate()
        switch sender.tag {
        case 1, 5:
            pop()
        case 2:
            // 重新拍照
            againPhotoClick()
        case 3:
            // 拍照 - 防连点
            sender.isEnabled = false
            takePicture()
            // 使用GCD在3秒后重新启用按钮
            DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                sender.isEnabled = true
            }
        case 4:
            // 选择照片
            confirmSelectPhoto()
        case 6:
            // 开启、关闭手电筒
            GlobalMethod.toggleFlashlight()
        default:
            break
        }
    }

    // MARK: - request
    func requestOSSUploadPositive() {
        GlobalMethod.showLoadingView()
        HomeRequestApi.uploadImage(
            shed: "2",
            carry: productCode,
            wisest: "11",
            image: image,
            rag: cardType
        ) { _, responseData in
            GlobalMethod.hideLoadingView()
            guard let res = responseData as? [String: Any] else { return }
            GlobalMethod.hideLoadingView()
            if let model = ModelUserIdentityInfoOther.deserialize(from: res) {
                if let block = self.blockUploadImageSuccess {
                    block(model)
                }
            }
            GB_Nav?.popViewController(animated: true)
        } failure: { _, _ in
            GlobalMethod.hideLoadingView()
            self.againPhotoClick()
        }
    }

}
